package com.index.search;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * 查
 */
public class IndexSearchManager {
    //当返现一段代码出现超过两次时 就要考虑抽取代码了
    public TransportClient getTransportClient() throws UnknownHostException {
        //1 : 配置集群的名字，EMPTY不写， 默认是：'elasticsearch'
        Settings settings = Settings.EMPTY;

        //连接的集群不是默认名
        /* Settings settings = Settings.builder().put("cluster.name","cluster-es")
                //.put("number_of_shards",10)    //设置分片数量
                //.put("number_of_replicas",2)  //设置备份多少份
                .build();*/

        //2： 建立TransportClient 对象完成对es服务调用 配置es服务的ip和端口  与ElasticSearch服务器的数据传
        // 输（即检索与创建）的客户端
        TransportClient transportClient = new PreBuiltTransportClient(settings);

        //3：通过传输客户端添加服务器信息  : es服务器的IP 与 端口 端口是9300 通过协议去连接的 使用的端口是9300
        transportClient.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
        //使用集群的时候，各个es服务器的地址都需要指定
        //transportClient.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9301));
        //transportClient.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9302));

        //返回
        return transportClient;
    }

    // matchAllQuery 匹配所有 或者说 搜索全部
    public void matchAllQuery() throws UnknownHostException {
        //1：搜索搜索条件
        QueryBuilder queryBuilder =  QueryBuilders.matchAllQuery();
        //  搜索全部
        this.searchMain(queryBuilder);
    }


    // 词条搜索
    public void termQuery() throws UnknownHostException {
        //1：搜索搜索条件
        //根据文档id去搜索是可以搜索到结果的，因为分词器分词式只是对field字段去分词 索引字段 type字段是不会分词的
        //QueryBuilder queryBuilder =  QueryBuilders.termQuery("_id","AWuEHXM2fcqMpk7eV-a_");

        // 如果没有配置ik分词器，termquery搜索一个词是搜索不到结果，为什么，因为es服务进行文档创建时分词是标准分词
        //QueryBuilder queryBuilder =  QueryBuilders.termQuery("title","习近平");
        QueryBuilder queryBuilder =  QueryBuilders.termQuery("title","搜索");
        //  搜索全部
        searchMain(queryBuilder);
    }

    // 关键词搜索，语义搜索，句子搜索
    public void queryStringQuery() throws UnknownHostException {
        //1：搜索搜索条件 queryString 会使用分词器去对搜索关键词进行分词  注意 只有term词条搜索不会对搜索条件分词
        //如果没有在es服务器配置ik分词器，就是用标准分词器
        QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("习近平").defaultField("title");
        //  搜索全部
        searchMain(queryBuilder);
    }

    //id搜索器：直接按照document的id去检索
    public void idsQuery() throws UnknownHostException {
        //1：搜索搜索条件
        QueryBuilder queryBuilder =  QueryBuilders.idsQuery("article").addIds("AWuEHXM2fcqMpk7eV-a_","3");
        //  搜索全部
        searchMain(queryBuilder);
    }

    //模糊搜索
    public void wildcardQuery() throws UnknownHostException {
        //1：搜索搜索条件
        //QueryBuilder queryBuilder =  QueryBuilders.wildcardQuery("title","习近平山西人");
        QueryBuilder queryBuilder =  QueryBuilders.wildcardQuery("title","搜索");
        //  搜索全部
        searchMain(queryBuilder);
    }



    //搜索主方法：叼
    private void searchMain(QueryBuilder queryBuilder) throws UnknownHostException {
        //1：搜索条件由方法调用处传入

        // 2:创建搜索对象
        SearchResponse searchResponse =  getTransportClient().prepareSearch("hyh_blog").setTypes("article").setQuery(queryBuilder).get();
        //SearchResponse searchResponse =  getTransportClient().prepareSearch("blog").setTypes("article").setQuery(queryBuilder).get();

        //3:获取搜索的结果
        SearchHits searchHits =  searchResponse.getHits();

        //4: 搜索搜索结果的总数
        System.out.println("一共搜索到：" + searchHits.getTotalHits() +"条记录");

        //5：遍历搜索的结果
        for (SearchHit searchHit : searchHits) {
            // 返回整个json给你看
            System.out.println(searchHit.getSourceAsString());
            // 返回整个document对象
            java.util.Map<String,Object> map = searchHit.getSourceAsMap();
            System.out.println(map.get("id"));
            System.out.println(map.get("title"));
            System.out.println(map.get("content"));
        }

        // 6：释放资源
        getTransportClient().close();
    }



    //搜索主方法：加上排序与分页
    private void searchMain2(QueryBuilder queryBuilder, boolean idFlag, int pageNo, int pageSize) throws UnknownHostException {
        //1：搜索条件由方法调用处传入

        // 2:创建搜索对象
        SearchResponse searchResponse =
                getTransportClient().prepareSearch("hyh_blog").setTypes("article").setQuery(queryBuilder)
                        .addSort("id", idFlag ? SortOrder.DESC : SortOrder.ASC)   //排序
                        .setFrom((pageNo - 1) * pageSize)  //分页
                        .setSize(pageSize)   //分页
                        .get();
        //SearchResponse searchResponse =  getTransportClient().prepareSearch("blog").setTypes("article").setQuery(queryBuilder).get();

        //3:获取搜索的结果
        SearchHits searchHits =  searchResponse.getHits();

        //4: 搜索搜索结果的总数
        System.out.println("一共搜索到：" + searchHits.getTotalHits() +"条记录");

        //5：遍历搜索的结果
        for (SearchHit searchHit : searchHits) {
            // 返回整个json给你看
            System.out.println(searchHit.getSourceAsString());
            // 返回整个document对象
            java.util.Map<String,Object> map = searchHit.getSourceAsMap();
            System.out.println(map.get("id"));
            System.out.println(map.get("title"));
            System.out.println(map.get("content"));
        }

        // 6：释放资源
        getTransportClient().close();
    }
}
